package org.example.java.util.concurrency.atomic;

/**
 * Created by Juntao.Zhang on 2014/9/10.
 */

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReferenceArray;

public class AtomicReferenceArrayTest {

  static AtomicReferenceArray<String> ara = new AtomicReferenceArray<String>(10);

  static class AddThread implements Runnable {

    private String name;

    AddThread(String name) {
      this.name = name;
    }

    @Override
    public void run() {
      try {
        //sets value at the index 1
        System.out.println(this.toString() + " : set ref");
        ara.set(0, "ref");
        TimeUnit.MILLISECONDS.sleep(20);
        //at index 0, if current reference is "ref" then it changes as newref
        System.out.println(this.toString() + " : compareAndSet ref newref");
        System.out.println(this.toString() + ara.compareAndSet(0, "ref", "newref"));
        //at index 0, if current value is newref, then it is sets as finalref
        TimeUnit.MILLISECONDS.sleep(20);
        System.out.println(this.toString() + " : weakCompareAndSet newref finalref");
        System.out.println(this.toString() + ara.weakCompareAndSet(0, "newref", "finalref"));
        System.out.println(this.toString() + " : " + ara.get(0));
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }

    @Override
    public String toString() {
      return "AddThread{" +
          "name='" + name + '\'' +
          '}';
    }
  }

  public static void main(String... args) {
    new Thread(new AddThread("thread1")).start();
    new Thread(new AddThread("thread2")).start();
  }
}
